tree grammar ConstScope;

options {
  language = Java;
  output = AST;
  tokenVocab = TreeConstruction;
  ASTLabelType = InterAST;
  filter = true;
}

@header
{
  package ru.msu.cmc.sp.oberon2;
  import ru.msu.cmc.sp.oberon2.exceptions.*;
}

@members {
  SymbolTable symtab;
  Symbol cons;
  Scope currentScope = null;
  String source; 
  public ConstScope(TreeNodeStream input, SymbolTable symtab, String src) {
    this(input);
    this.symtab = symtab;
    this.source = src;
    currentScope = symtab.globals;
  }
}

topdown 
    :    constDeclaration 
    ;



constDeclaration
    : ^(CONST_DECL IDENT (i = iconst | r = rconst | b = bconst | c = cconst | str = strconst))
    {
        Symbol s;
        if (i != null) {
            s = new Symbol($IDENT.text, $i.type);
            s.value = $i.value;
        } else if (r != null) {
            s = new Symbol($IDENT.text, $r.type);
            s.value = $r.value;
        } else if (b != null) {
            s = new Symbol($IDENT.text, SymbolTable._boolean);
            s.value = $b.value;
        } else if (c != null) {
            s = new Symbol($IDENT.text, SymbolTable._char);
            s.value = $c.value;
        } else if (str != null) {
            s = new Symbol($IDENT.text, new ArrayType(SymbolTable._char, $str.value.length()));
            s.value = $str.value;
        } else {
            throw new RecognitionError($IDENT, "Dead code is ALIVE!!!");
        } 
        s.constant = true;
        currentScope.define(s);
    }
    ;
    
iconst returns [String value, Type type]
    : ^(INTCONST INTEGER)   { $value = $INTEGER.text; $type = SymbolTable._int;} 
    | ^(SHORTCONST INTEGER) { $value = $INTEGER.text; $type = SymbolTable._shortint;}   
    | ^(LINTCONST INTEGER)  { $value = $INTEGER.text; $type = SymbolTable._longint;}  
    ;  

rconst returns [String value, Type type]
    : ^(REALCONST REAL)     { $value = $REAL.text; $type = SymbolTable._real;} 
    | ^(LREALCONST REAL)    { $value = $REAL.text; $type = SymbolTable._longreal;} 
    ;
  
bconst returns [String value]
    : ^(BOOLCONST BOOLEAN)   { $value = $BOOLEAN.text;}  
    ; 

cconst returns [String value]
    : ^(CHARCONST CHAR)   { $value = $CHAR.text;}  
    ; 
    
strconst returns [String value]
    : ^(STRCONST STRING)   { $value = $STRING.text;}  
    ; 
    